import javafx.animation.AnimationTimer;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

public class GameScene {
    private GameManager gameManager;
    private Board board;
    private Canvas gameCanvas;
    private Canvas nextPieceCanvas;
    private GraphicsContext gc;
    private GraphicsContext nextPieceGc;
    private AnimationTimer gameLoop;
    private long lastUpdateTime = 0;
    private int cellSize = 30;
    private int width = 10;
    private int height = 20;
    private int initialSpeed = 5;
    private boolean isPaused = false;
    private boolean isGameOver = false;
    private Text scoreText;
    private Text levelText;
    private Text linesText;
    
    public GameScene(GameManager gameManager) {
        this.gameManager = gameManager;
    }
    
    public void setBoardDimensions(int width, int height) {
        this.width = width;
        this.height = height;
    }
    
    public void setInitialSpeed(int speed) {
        this.initialSpeed = speed;
    }
    
    public Scene createScene() {
        BorderPane root = new BorderPane();
        root.setStyle("-fx-background-color: #333333;");
        
        // 创建游戏画布
        gameCanvas = new Canvas(width * cellSize, height * cellSize);
        gc = gameCanvas.getGraphicsContext2D();
        
        // 创建右侧面板（分数、下一个方块等）
        VBox rightPanel = new VBox(20);
        rightPanel.setPadding(new javafx.geometry.Insets(20));
        
        Text scoreLabel = new Text("分数");
        scoreLabel.setFont(Font.font("Arial", 18));
        scoreLabel.setFill(Color.WHITE);
        
        scoreText = new Text("0");
        scoreText.setFont(Font.font("Arial", 24));
        scoreText.setFill(Color.WHITE);
        
        Text levelLabel = new Text("等级");
        levelLabel.setFont(Font.font("Arial", 18));
        levelLabel.setFill(Color.WHITE);
        
        levelText = new Text("1");
        levelText.setFont(Font.font("Arial", 24));
        levelText.setFill(Color.WHITE);
        
        Text linesLabel = new Text("已消除行数");
        linesLabel.setFont(Font.font("Arial", 18));
        linesLabel.setFill(Color.WHITE);
        
        linesText = new Text("0");
        linesText.setFont(Font.font("Arial", 24));
        linesText.setFill(Color.WHITE);
        
        Text nextPieceLabel = new Text("下一个方块");
        nextPieceLabel.setFont(Font.font("Arial", 18));
        nextPieceLabel.setFill(Color.WHITE);
        
        // 下一个方块预览区域
        nextPieceCanvas = new Canvas(4 * cellSize, 4 * cellSize);
        nextPieceGc = nextPieceCanvas.getGraphicsContext2D();
        
        rightPanel.getChildren().addAll(
            scoreLabel, scoreText, 
            levelLabel, levelText,
            linesLabel, linesText,
            nextPieceLabel, nextPieceCanvas
        );
        
        // 底部控制说明
        VBox bottomPanel = new VBox(10);
        bottomPanel.setPadding(new javafx.geometry.Insets(10));
        
        Text controlsText = new Text("控制: ←→ 移动, ↑ 旋转, ↓ 加速下落, 空格 硬降, P 暂停, R 重新开始");
        controlsText.setFont(Font.font("Arial", 12));
        controlsText.setFill(Color.LIGHTGRAY);
        
        bottomPanel.getChildren().add(controlsText);
        
        // 将所有组件添加到根面板
        root.setCenter(gameCanvas);
        root.setRight(rightPanel);
        root.setBottom(bottomPanel);
        
        Scene scene = new Scene(root, width * cellSize + 200, height * cellSize + 50);
        
        // 键盘控制
        scene.setOnKeyPressed(event -> {
            if (isGameOver) {
                return;
            }
            
            if (event.getCode() == KeyCode.P) {
                togglePause();
                return;
            }
            
            if (event.getCode() == KeyCode.R) {
                resetGame();
                return;
            }
            
            if (isPaused) {
                return;
            }
            
            switch (event.getCode()) {
                case LEFT:
                    board.movePieceLeft();
                    break;
                case RIGHT:
                    board.movePieceRight();
                    break;
                case DOWN:
                    board.movePieceDown();
                    break;
                case UP:
                    board.rotatePieceClockwise();
                    break;
                case Z:
                    board.rotatePieceCounterClockwise();
                    break;
                case SPACE:
                    board.hardDrop();
                    break;
            }
        });
        
        return scene;
    }
    
    public void startGame() {
        board = new Board(width, height);
        board.setInitialSpeed(initialSpeed);
        board.setScoreListener(this::updateScoreDisplay);
        board.setLevelListener(this::updateLevelDisplay);
        board.setLinesListener(this::updateLinesDisplay);
        board.setNextPieceListener(this::updateNextPieceDisplay);
        board.setGameOverListener(this::gameOver);
        
        resetGame();
        
        // 游戏主循环
        gameLoop = new AnimationTimer() {
            @Override
            public void handle(long currentNanoTime) {
                if (isPaused || isGameOver) {
                    return;
                }
                
                long elapsedNanos = currentNanoTime - lastUpdateTime;
                double elapsedSeconds = elapsedNanos / 1_000_000_000.0;
                
                if (elapsedSeconds >= board.getDropInterval()) {
                    board.movePieceDown();
                    lastUpdateTime = currentNanoTime;
                }
                
                render();
            }
        };
        
        lastUpdateTime = System.nanoTime();
        gameLoop.start();
    }
    
    private void resetGame() {
        board.reset();
        isPaused = false;
        isGameOver = false;
        updateScoreDisplay(0);
        updateLevelDisplay(1);
        updateLinesDisplay(0);
        updateNextPieceDisplay(board.getNextPiece());
    }
    
    private void togglePause() {
        isPaused = !isPaused;
    }
    
    private void gameOver() {
        isGameOver = true;
        gameLoop.stop();
        gameManager.showGameOver(board.getScore());
    }
    
    private void updateScoreDisplay(int score) {
        scoreText.setText(String.valueOf(score));
    }
    
    private void updateLevelDisplay(int level) {
        levelText.setText(String.valueOf(level));
    }
    
    private void updateLinesDisplay(int lines) {
        linesText.setText(String.valueOf(lines));
    }
    
    private void updateNextPieceDisplay(Piece nextPiece) {
        nextPieceGc.clearRect(0, 0, nextPieceCanvas.getWidth(), nextPieceCanvas.getHeight());
        
        if (nextPiece != null) {
            int[][] shape = nextPiece.getShape();
            Color color = nextPiece.getColor();
            
            for (int y = 0; y < shape.length; y++) {
                for (int x = 0; x < shape[y].length; x++) {
                    if (shape[y][x] != 0) {
                        // 居中显示下一个方块
                        double displayX = (nextPieceCanvas.getWidth() - shape[0].length * cellSize) / 2 + x * cellSize;
                        double displayY = (nextPieceCanvas.getHeight() - shape.length * cellSize) / 2 + y * cellSize;
                        
                        nextPieceGc.setFill(color);
                        nextPieceGc.fillRect(displayX, displayY, cellSize, cellSize);
                        
                        nextPieceGc.setStroke(Color.BLACK);
                        nextPieceGc.strokeRect(displayX, displayY, cellSize, cellSize);
                    }
                }
            }
        }
    }
    
    private void render() {
        // 清空画布
        gc.clearRect(0, 0, gameCanvas.getWidth(), gameCanvas.getHeight());
        
        // 绘制已固定的方块
        Color[][] boardState = board.getBoardState();
        for (int y = 0; y < boardState.length; y++) {
            for (int x = 0; x < boardState[y].length; x++) {
                if (boardState[y][x] != null) {
                    gc.setFill(boardState[y][x]);
                    gc.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    
                    gc.setStroke(Color.BLACK);
                    gc.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                }
            }
        }
        
        // 绘制当前方块
        Piece currentPiece = board.getCurrentPiece();
        if (currentPiece != null) {
            int[][] shape = currentPiece.getShape();
            Color color = currentPiece.getColor();
            int x = currentPiece.getX();
            int y = currentPiece.getY();
            
            for (int i = 0; i < shape.length; i++) {
                for (int j = 0; j < shape[i].length; j++) {
                    if (shape[i][j] != 0) {
                        gc.setFill(color);
                        gc.fillRect((x + j) * cellSize, (y + i) * cellSize, cellSize, cellSize);
                        
                        gc.setStroke(Color.BLACK);
                        gc.strokeRect((x + j) * cellSize, (y + i) * cellSize, cellSize, cellSize);
                    }
                }
            }
        }
        
        // 如果游戏暂停，显示暂停信息
        if (isPaused) {
            gc.setFill(Color.rgb(0, 0, 0, 0.7));
            gc.fillRect(0, 0, gameCanvas.getWidth(), gameCanvas.getHeight());
            
            gc.setFill(Color.WHITE);
            gc.setFont(Font.font("Arial", 30));
            gc.fillText("游戏暂停", gameCanvas.getWidth() / 2 - 80, gameCanvas.getHeight() / 2);
            gc.setFont(Font.font("Arial", 16));
            gc.fillText("按 P 继续", gameCanvas.getWidth() / 2 - 40, gameCanvas.getHeight() / 2 + 30);
        }
    }
}
